#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ncurses.h>

#define Board_Width 8
#define Board_Height 8
#define Empty_Square '~'

struct Square {
  int X;
  int Y;
  char Symbol;
  bool IsWhitePiece;
};

bool CheckLegalMove(struct Square Board[Board_Width][Board_Height],
                    uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);

bool CheckLegalMove(struct Square Board[Board_Width][Board_Height],
                    uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2) {
	if (Board[y1][x1].Symbol == 'C'){
	  if (x1 == x2 || y1 == y2){
	  /*TODO: scan for pieces in the way of every piece
	  you may need to list of the squares on the board which make up the path of the movement
	  in order to detect collisions.
	  A piece should only be able to collide with one other piece(a piece to be taken).*/
	    return true;
	  }
	  else{
	    return false;
	  }
	}
	}

void DrawBoard(struct Square Board[Board_Width][Board_Height]){
	for (int i = 0; i < Board_Height; i++){
		for (int j = 0; j < Board_Width; j++){
			addch(Board[i][j].Symbol | A_BOLD);
			}
		addch('\n');
		}
	}

int main (int argc, char* argv[]){
  
  /*Define the board as a 2d map of squares.*/
  struct Square Board[Board_Width][Board_Height];
  
  Board[0][0].Symbol = 'C';
  Board[0][1].Symbol = 'B';
  Board[0][2].Symbol = 'H';
  Board[0][3].Symbol = 'Q';
  Board[0][4].Symbol = 'K';
  Board[0][5].Symbol = 'H';
  Board[0][6].Symbol = 'B';
  Board[0][7].Symbol = 'C';

  Board[1][0].Symbol = 'P';
  Board[1][1].Symbol = 'P';
  Board[1][2].Symbol = 'P';
  Board[1][3].Symbol = 'P';
  Board[1][4].Symbol = 'P';
  Board[1][5].Symbol = 'P';
  Board[1][6].Symbol = 'P';
  Board[1][7].Symbol = 'P';
 
  /*Fill in the middle of the board with empty spaces.*/
  for (int i = 2; i < Board_Height-2; i++){
	  for (int j = 0; j < Board_Width; j++){
		  Board[i][j].Symbol = Empty_Square;
		  }
	  }
  Board[6][0].Symbol = 'P';
  Board[6][1].Symbol = 'P';
  Board[6][2].Symbol = 'P';
  Board[6][3].Symbol = 'P';
  Board[6][4].Symbol = 'P';
  Board[6][5].Symbol = 'P';
  Board[6][6].Symbol = 'P';
  Board[6][7].Symbol = 'P';
  
  Board[7][0].Symbol = 'C';
  Board[7][1].Symbol = 'B';
  Board[7][2].Symbol = 'H';
  Board[7][3].Symbol = 'Q';
  Board[7][4].Symbol = 'K';
  Board[7][5].Symbol = 'H';
  Board[7][6].Symbol = 'B';
  Board[7][7].Symbol = 'C';
  
  
  char Input[64];
  char MsgBuffer[64];
  int PlayerN = 1;
  
  //Setup ncurses
  initscr();
  noecho();
  wrefresh(stdscr);
  
  memset(MsgBuffer, 0, 64);
  
  while (true){
    wmove(stdscr, 0, 0);
    DrawBoard(Board);
    echo();
    printw(MsgBuffer);printw("\n");
    printw("Player %d's move\n", PlayerN);
    printw("Please use the format x1 y1 x2 y2 ");
    printw("separated by white spaces.\n");
    printw("Move: ");
    getnstr(Input, 64);
    memset(MsgBuffer, 0, 64);
    
    /*Prepare to process user input*/
    
    unsigned int x1 = 0;
    unsigned int y1 = 0;
    unsigned int x2 = 0;
    unsigned int y2 = 0;
    
    /*Load coordinates from user input*/
    sscanf(Input, "%d %d %d %d", &x1, &y1, &x2, &y2);
    
    /*Check if the move is legal if so then move.
    TODO: check if any pieces are in the way of the move,
    if so then dissallow.
    Also if piece is of same team disallow move.
    
    */
    if (CheckLegalMove(Board, x1, y1, x2, y2) == true){
      Board[y2][x2].Symbol = Board[y1][x1].Symbol;
      Board[y1][x1].Symbol = Empty_Square;
      }
    else{
      snprintf(MsgBuffer, sizeof(MsgBuffer), "Invalid move for %c\n", Board[y1][x1].Symbol);
    }
    
    /*Process user input*/
    /*Draft plan:
     * Take user input and check if legal move.
     * If the return is true then call the move function to perform the move.
     * The move will overwrite any pieces already there.
     * Otherwise print to the screen notifying the user that the attempted move
     * is unallowed.
     * 
     * Once the king of an opposing team has been taken print a end game screen and then
     * start over.
     * */
    
    noecho();
    wrefresh(stdscr);
    erase();
  }
  
  endwin();
  
  return 0;
}
